package com.xc.common.tool;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.beust.jcommander.internal.Lists;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Sets;
import com.xc.common.object.LocalDateConverter;
import com.xc.common.object.LocalDateTimeConverter;
import com.xc.common.py4j.Converter;
import com.xc.common.py4j.PinyinConverter;
import com.xc.common.py4j.exception.IllegalPinyinException;
import com.xc.common.snowid.SnowflakeIdWorker;
import com.xc.common.snowid.SnowflakeManager;
import com.xc.sys.entity.SysOrganizationEntity;
import com.xc.sys.entity.SysUserEntity;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.BigDecimalConverter;
import org.apache.commons.lang3.StringUtils;

public class Helper {
	private static SnowflakeManager snowflakeManager = null;
	static {
		snowflakeManager = new SnowflakeManager(1,1);
	}
	public static Long getSnowId() {
		try {
			return snowflakeManager.nextValue();
		} catch (Exception e) {
			return null;
		}
	}
	public static BigDecimal newBigDecimal(Double num) {
		BigDecimal bnum = new BigDecimal("0");
		if (num != null) {
			bnum = new BigDecimal(num + "");
		}
		return bnum;
	}
	public static Integer[] str2integerArr(String ids) {
		String[] idarrs = StringUtils.split(ids,",");
		Integer[] idarr = new Integer[idarrs.length];
		for (int i=0;i<idarrs.length;i++) {
			if(idarrs[i].length()>0)
			idarr[i] = Integer.valueOf(idarrs[i]);
		}
		return idarr;
	}
	public static Long[] str2longArr(String ids) {
		String[] idarrs = StringUtils.split(ids,",");
		Long[] idarr = new Long[idarrs.length];
		for (int i=0;i<idarrs.length;i++) {
			if(idarrs[i].length()>0)
				idarr[i] = Long.valueOf(idarrs[i]);
		}
		return idarr;
	}
	public static BigDecimal add(Double... nums) {
		BigDecimal[] bNums = new BigDecimal[nums.length];
		int i = 0;
		BigDecimal bTotal = new BigDecimal("0");
		for(BigDecimal bNum : bNums) {
			bNum = Helper.newBigDecimal(nums[i++]);
			bTotal = bTotal.add(bNum);
		}
		return bTotal;
	}
	public static String getThisMonthLastDate() {
		LocalDate today = LocalDate.now();
		LocalDate lastDay = today.with(TemporalAdjusters.lastDayOfMonth());
		DateTimeFormatter fm = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		return lastDay.format(fm);
	}
	/**
	 * 
	 * @Description: 字符串转换成set
	 * @author: 曾平
	 * @date:   2021年6月17日 下午2:33:57
	 */
	public static Set<Long> covertArr2Ls(String str) {
		return Lists.newArrayList(str.split(",")).stream().map(v->{return Long.valueOf(v);}).collect(Collectors.toSet());
	}
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static<T> T map2Bean(T bean,Map map) {
		BigDecimalConverter bd = new BigDecimalConverter(null);
		ConvertUtils.register(bd, java.math.BigDecimal.class); 
		ConvertUtils.register(new LocalDateConverter(),LocalDate.class);
		ConvertUtils.register(new LocalDateTimeConverter(),LocalDateTime.class);
		try {
			BeanUtils.populate(bean, map);
		} catch (IllegalAccessException | InvocationTargetException e) {
			e.printStackTrace();
		}  
		return bean;
	}
	public static HashMap<String,String> request2map(HttpServletRequest request) {
		HashMap<String,String> params = new HashMap<>();
        Map<String, String[]> paramNameMap = request.getParameterMap();
        Set<Entry<String, String[]>> pes = paramNameMap.entrySet();
        for(Entry<String, String[]> entry : pes) {
        	String key = entry.getKey();
        	String[] values = entry.getValue();
        	params.put(key, values[0]);
        }
        return params;
	}
	@SuppressWarnings("unchecked")
	public static<T> T extractBeanFromMap(HashMap<String, String> params,String key,T t) {
		ObjectMapper mapper = new ObjectMapper();
		JsonNode entityNode = null;
		try {
			entityNode = mapper.readTree(params.get(key));
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Map<String, String> eqEquipmentMap = mapper.convertValue(entityNode, Map.class);
		Helper.map2Bean(t, eqEquipmentMap);
		return t;
	}
	/**
	 * 将字符串转换为LocalDateTime
	 */
	public static LocalDateTime String2LocalDateTime(String timestr) {
	     DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	     LocalDateTime datetime = LocalDateTime.parse(timestr,fmt);
	     return datetime;
	}
	public static SysUserEntity getMe(HttpServletRequest request) {
		SysUserEntity me = (SysUserEntity) request.getSession().getAttribute("me");
		return me;
	}

	/**
	 * 
	 * @作者：曾平
	 * @日期：2020年12月27日 下午2:40:36   
	 * @功能：计算间隔多少天
	 */
	public static long calcDateGap( LocalDate beginDate ,LocalDate endDate) {
		long days = beginDate.until(endDate,ChronoUnit.DAYS);
		return days;
	}
	/**
	 * 
	 * 作者：曾平
	 * 日期：2020年4月16日 上午11:19:03 
	 * 描述：计算年月日
	 */
	public static String calcYMD( Date beginDate ,LocalDate endDate, String pattern) {
		LocalDate localBeginDate = Helper.date2LocalDate(beginDate);
		long workMonths = localBeginDate.until(endDate,ChronoUnit.MONTHS);
		long workYears = workMonths / 12; 
		workMonths = workMonths % 12;    //月份等于除不尽的余数
		LocalDate anniversary = localBeginDate.plusYears(workYears);
		
		Period p = Period.between(anniversary,endDate);
		String workYear = workYears+"年" +workMonths+"月"+p.getDays()+"天";
		return workYear;
	}
	/**
	 * 
	 * 作者：曾平
	 * 日期：2020年4月16日 上午11:19:03 
	 * 描述：计算年月日
	 */
	public static String calcYMD( LocalDate beginDate ,LocalDate endDate, String pattern) {
		long workMonths = beginDate.until(endDate,ChronoUnit.MONTHS);
		long workYears = workMonths / 12; 
		workMonths = workMonths % 12;    //月份等于除不尽的余数
		LocalDate anniversary = beginDate.plusYears(workYears);
		Period p = Period.between(anniversary,endDate);
		String workYear = workYears+"年" +workMonths+"月"+p.getDays()+"天";
		return workYear;
	}
	public static LocalDate[] convertCreateTimeVars(String createTimeRegion) {
		if ((createTimeRegion != null) && (!createTimeRegion.equals("")) && (createTimeRegion.indexOf("至") > 0)) {
			String d1 = StringUtils.substringBefore(createTimeRegion, "至").trim();
			String d2 = StringUtils.substringAfter(createTimeRegion, "至").trim();
			DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
			LocalDate createTime = LocalDate.parse(d1, fmt);
			LocalDate createTime2 = LocalDate.parse(d2, fmt);
			return new LocalDate[] { createTime, createTime2 };
		}
		return null;
	}
	public static String genCodeWithUserName(SysUserEntity user) {
		DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyMMddHHmmss");
		String str = fmt.format(LocalDateTime.now());
		String random = (int) (Math.random() * 100.0D) + "";
		String letter = random+(user.getMobileno()==null?"":StringUtils.substring(user.getMobileno(), 7)) + StringUtils.substring(user.getId(),0,3);
		String code = letter + str;
		return code;
	}
	//把汉字转换成简拼和全拼
	public static String[] getPinyin(String name) {
		String[] pinyins = new String[2];
		String letters[] = null;
		if(name.indexOf(" ")!=-1) {
			letters = StringUtils.split(name," ");
		}else {
			letters = name.split("");
		}
		List<String> initialLetters = new ArrayList<>();
		List<String> fullPinyins = new ArrayList<>();
		Converter converter = new PinyinConverter();
		try {
			for (String letter : letters){
				String py = converter.getPinyin(letter);
				initialLetters.add(py.substring(0,1));
				fullPinyins.add(py);
			}
		}catch(IllegalPinyinException e) {
			
		}
		pinyins[0] = StringUtils.join(initialLetters,"");
		pinyins[1] = StringUtils.join(fullPinyins,"");
		return pinyins;
	}
	public static Byte[] lowercaseByteArr(byte[] bytes) {
		Byte[] bb = new Byte[bytes.length];
		int i = 0;
		for (byte b : bytes) {
			bb[(i++)] = Byte.valueOf(b);
		}
		return bb;
	}

	public static synchronized String genCode(String prefix) {
		LocalDateTime now = LocalDateTime.now();
		DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyMMddHHmmss");
		String random = (int) (Math.random() * 100.0D) + "";
		random = StringUtils.leftPad(random, 2,"0");
		String code = fmt.format(now);
		String[] arr = random.split("");
		for (String s : arr) {
			double i = Math.random() * 12.0D;
			int index = (int) i;
			String a = StringUtils.substring(code, 0, index);
			String b = StringUtils.substring(code, index);
			code = a + s + b;
		}
		return prefix + code;
	}
	public static synchronized String genOrderCode(String prefix,int length) {
		LocalDateTime now = LocalDateTime.now();
		DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyMMddHHmmss");
		String l = StringUtils.rightPad("1", length,"0");
		Double su = Double.valueOf(l);
		String random = (int) (Math.random() * su) + "";
		random = StringUtils.leftPad(random, 2,"0");
		String code = fmt.format(now);
		String[] arr = random.split("");
		for (String s : arr) {
			double i = Math.random() * 12.0D;
			int index = (int) i;
			String a = StringUtils.substring(code, 0, index);
			String b = StringUtils.substring(code, index);
			code = a + s + b;
		}
		return prefix + code;
	}
	public static synchronized String genTimeCode(String prefix) {
		LocalDateTime now = LocalDateTime.now();
		DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyMMddHHmmss");
		String code = fmt.format(now);
		return prefix + code;
	}

	public static synchronized String genRandomCode(String prefix) {
		LocalDateTime now = LocalDateTime.now();
		DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyMMddHHmmss");
		String random = (int) (Math.random() * 1000.0D) + "";
		String code = fmt.format(now);
		String[] arr = random.split("");
		for (String s : arr) {
			double i = Math.random() * 12.0D;
			int index = (int) i;
			String a = StringUtils.substring(code, 0, index);
			String b = StringUtils.substring(code, index);
			code = a + s + b;
		}
		return prefix + code;
	}

	public static Date localDate2Date(LocalDate localDate) {
		if (null == localDate) {
			return null;
		}
		ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
	    return Date.from(zonedDateTime.toInstant());
	}
	public static LocalDate date2LocalDate(Date date) {
		if (null == date) {
			return null;
		}
		Instant d = date.toInstant();
		return d.atZone(ZoneId.systemDefault()).toLocalDate();
	}
	public static LocalDateTime date2LocalDateTime(Date date) {
		if (null == date) {
			return null;
		}
		return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
	}

	public static LocalDateTime date2LocalTime(Date date) {
		Instant instant = date.toInstant();
		ZoneId zone = ZoneId.systemDefault();
		LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
		return localDateTime;
	}

	// 根据当前用户所在的部门，获取其祖宗节点的code的集合
	public static HashSet<String> getDirectLineCodes(SysOrganizationEntity mystore) {
		String code = mystore.getCode();
		HashSet<String> indexidSet = Sets.newHashSet();
		while (code.length() > 3) {
			indexidSet.add(code);
			code = StringUtils.substring(code, 0, code.length()-3);
		}
		return indexidSet;
	}
	// 带圆点
	public static String getFullSuffix(String fileName) {
		if (StringUtils.isEmpty(fileName)) {
			return "";
		}
		String suffix = fileName.substring(fileName.lastIndexOf("."));
		return suffix;
	}
	
	public static String getSuffix(String fileName) {
		if (StringUtils.isEmpty(fileName)) {
			return "";
		}
		String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
		return suffix;
	}
	public static String convertFileSize(long size) {
		BigDecimal bSize = new BigDecimal(size+"");
		String bigsize = "";
		long g = 1024*1024*1024;
		long m = 1024*1024;
		long k = 1024;
		if(size>=g) {
			BigDecimal bg = new BigDecimal(g+"");
			BigDecimal a = bSize.divide(bg, 1, RoundingMode.HALF_EVEN);
			bigsize = a + "G";
		}else if(size>=m) {
			BigDecimal bg = new BigDecimal(m+"");
			BigDecimal a = bSize.divide(bg, 1, RoundingMode.HALF_EVEN);
			bigsize = a + "M";
		}else if(size>=k){
			BigDecimal bg = new BigDecimal(k+"");
			BigDecimal a = bSize.divide(bg, 1, RoundingMode.HALF_EVEN);
			bigsize = a + "KB";
		}else {
			bigsize = size + "B";
		}
		return bigsize;
	}

	public static void main(String[] args) {
		SnowflakeIdWorker sm = new SnowflakeIdWorker(1);
		for(int i=0;i<100;i++) {
			long id = sm.nextId();
			System.out.println(id);
		}
	}
	
}
